﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using SocketGateway.DTO;
using SocketGateway.Tool;
using TK.TSocket;
using TouchSocket.Core;

namespace SocketGateway.Controllers
{
    /// <summary>
    /// 数据接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class DataController : ControllerBase
    {
        private readonly ITcpSocketServer _tcpSocketServer;
        private readonly IReceiveData _receiveData;
        private readonly IMemoryCache _memoryCache;

        /// <summary>
        /// ctor
        /// </summary>
        public DataController(
            ITcpSocketServer tcpSocketServer,
            IReceiveData receiveData,
            IMemoryCache memoryCache)
        {
            _tcpSocketServer = tcpSocketServer;
            _receiveData = receiveData;
            _memoryCache = memoryCache;
        }

        /// <summary>
        /// 获取框架数据
        /// </summary>
        [HttpGet("get.frame.config")]
        public async Task<string> GetFrameConfigAsync()
        {
            return await Task.FromResult(ToolHelper.GetFrameConfigJson());
        }

        /// <summary>
        /// 菜单列表
        /// </summary>
        [HttpGet("list.menu")]
        public async Task<List<MenuDto>> GetMenuListAsync()
        {
            return await Task.FromResult(Data.MenuData);
        }

        /// <summary>
        /// 监听器列表
        /// </summary>
        [HttpPost("list.listener")]
        public async Task<LayuiResultDto<List<ListenerDto>>> GetListenerListAsync()
        {
            var list = new List<ListenerDto>();
            if (_tcpSocketServer.TcpService?.Monitors != null)
                foreach (var item in _tcpSocketServer.TcpService.Monitors)
                    list.Add(new ListenerDto { Id = item.IPHost.Port, IP = item.IPHost.IP, Port = item.IPHost.Port, NetType = item.IPHost.AddressFamily.ToString() });
            return await Task.FromResult(LayuiResultDto<List<ListenerDto>>.Success(list, list.Count));
        }

        /// <summary>
        /// 新增编辑保存监听器
        /// </summary>
        [HttpPost("save.listener")]
        public async Task<BaseResultDto> SaveListenerAsync(ListenerDto model)
        {
            var oldKey = $":{model.Port}";
            if (model.Id.HasValue && model.Id.Value > 0)
                oldKey = $":{model.Id.Value}";
            var old = Data.Listener.FirstOrDefault(m => m.EndsWith(oldKey));
            if (old != null)
                Data.Listener.Remove(old);
            Data.Listener.Add($"{model.IP}:{model.Port}");
            var path = Path.Combine(AppContext.BaseDirectory, "DataConfig", "listener.json");
            Tool.ToolHelper.SaveJsonToFile(path, new Dictionary<string, List<string>> { { "listener", Data.Listener } });
            StopSocket(true);
            return await Task.FromResult(BaseResultDto.Success());
        }

        /// <summary>
        /// 删除监听器
        /// </summary>
        [HttpPost("delete.listener.{id}")]
        public async Task<BaseResultDto> DeleteListenerAsync(int? id)
        {
            if (Data.Listener.Count <= 1)
                return BaseResultDto.Fail("最后一个监听器禁止删除");
            var old = Data.Listener.FirstOrDefault(m => m.EndsWith($":{id}"));
            if (old != null)
                Data.Listener.Remove(old);
            var path = Path.Combine(AppContext.BaseDirectory, "DataConfig", "listener.json");
            Tool.ToolHelper.SaveJsonToFile(path, new Dictionary<string, List<string>> { { "listener", Data.Listener } });
            StopSocket(true);
            return await Task.FromResult(BaseResultDto.Success());
        }

        /// <summary>
        /// 开启SOKCET服务
        /// </summary>
        [HttpPost("start.listener")]
        public async Task<BaseResultDto> StartListenerAsync()
        {
            if (_tcpSocketServer.TcpService != null && _tcpSocketServer.TcpService.ServerState != TouchSocket.Sockets.ServerState.Running)
                _tcpSocketServer.Start(_receiveData);
            return await Task.FromResult(BaseResultDto.Success());
        }

        /// <summary>
        /// 停止SOKCET服务
        /// </summary>
        [HttpPost("stop.listener")]
        public async Task<BaseResultDto> StopListenerAsync()
        {
            StopSocket();
            return await Task.FromResult(BaseResultDto.Success());
        }

        /// <summary>
        /// socket客户端列表
        /// </summary>
        [HttpPost("list.socket.client")]
        public async Task<LayuiResultDto<List<SocketClientDto>>> GetSocketClientListAsync()
        {
            var list = new List<SocketClientDto>();
            var count = _tcpSocketServer.TcpService.SocketClients.Count;
            foreach (var item in _tcpSocketServer.TcpService.SocketClients.GetClients())
                list.Add(new SocketClientDto { Id = item.ID, ClientIP = item.IP, ClientPort = item.Port, ServerIP = item.ServiceIP, ServerPort = item.ServicePort });
            return await Task.FromResult(LayuiResultDto<List<SocketClientDto>>.Success(list, count));
        }

        /// <summary>
        /// 黑白名单配置保存
        /// </summary>
        [HttpPost("save.whiteblack")]
        public async Task<BaseResultDto> SaveWhiteBlackAsync(WhiteBlackDto model)
        {
            var tcpConfig = _tcpSocketServer.TcpService.Container.Resolve<TcpSocketServerConfig>();
            if (model.IpWhiteList?.Any() == true)
            {
                model.IpWhiteList = model.IpWhiteList.Where(m => !string.IsNullOrWhiteSpace(m)).ToList();
                tcpConfig.IpWhiteList.Clear();
                tcpConfig.IpWhiteList.AddRange(model.IpWhiteList);
            }
            if (model.IpBlackList?.Any() == true)
            {
                model.IpBlackList = model.IpBlackList.Where(m => !string.IsNullOrWhiteSpace(m)).ToList();
                tcpConfig.IpBlackList.Clear();
                tcpConfig.IpBlackList.AddRange(model.IpBlackList);
            }

            var path = Path.Combine(AppContext.BaseDirectory, "DataConfig", "white_black_acl.json");
            Tool.ToolHelper.SaveJsonToFile(path, model);

            return await Task.FromResult(BaseResultDto.Success());
        }

        /// <summary>
        /// 获取客户端日志
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        [HttpPost("list.log.{clientId}")]
        public async Task<LayuiResultDto<List<KeyValuePair<string,string>>>> GetLogListAsync(string clientId)
        {
            _memoryCache.Set(clientId, "1", DateTimeOffset.Now.AddMinutes(2));
            var result = new List<KeyValuePair<string, string>>();
            if (Data.LogData.TryGetValue(clientId, out var data))
                data.ForEach(m => { result.Add(new KeyValuePair<string, string>("log", m)); });

            return await Task.FromResult(LayuiResultDto<List<KeyValuePair<string, string>>>.Success(result, result.Count));
        }

        #region private methods
        /// <summary>
        /// 停止SOCKET服务
        /// </summary>
        private void StopSocket(bool isRestart = false)
        {
            _tcpSocketServer.Dispose();
            Data.LogData.Clear();
            if (isRestart)
                _tcpSocketServer.Start(_receiveData);
        }
        #endregion
    }
}
